package main

import (
	"encoding/csv"
	"flag"
	"log"
	"math/rand"
	"os"
	"time"
	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
	"image/draw"
	"image/color"
	"image"
)

func main() {
	filename := flag.String("data", "test.csv", "CSV data file")
	flag.Parse()
	file, err := os.Open(*filename)
	if err != nil {
		log.Panicln(err)

	}
	defer file.Close()
	reader := csv.NewReader(file)
	allWordsRaw, err := reader.ReadAll()
	if err != nil {
		log.Panicln(err)
	}

	guiLoop(allWordsRaw)
}

func turn2DTo1D(arr [][]string) []string {
	tmp := make([]string, 0)
	for _, value := range arr {
		for _, valueCol := range value {
			tmp = append(tmp, valueCol)
		}
	}
	return tmp
}

func generateRandomNumber(start int, end int, count int) []int {
	if end < start || (end-start) < count {
		return nil
	}
	nums := make([]int, 0)
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for len(nums) < count {
		num := r.Intn(end-start+1) + start
		exist := false
		for _, v := range nums {
			if v == num {
				exist = true
				break
			}
		}
		if !exist {
			nums = append(nums, num)
		}
	}
	return nums
}

func shuffle(arr []string) []string {
	tmp := make([]string, 0)
	randomNumbers := generateRandomNumber(0, len(arr)-1, len(arr)-1)
	for i := 0; i < len(arr)-1; i++ {
		tmp = append(tmp, arr[randomNumbers[i]])
	}
	return tmp
}

func getShuffleString(arr [][]string) string {
	for {
		tmp := shuffle(turn2DTo1D(arr))[generateRandomNumber(0, len(turn2DTo1D(arr))-2, 1)[0]]
		if tmp != "" && tmp != " " {
			return tmp
		}
	}
}
func guiLoop(arr [][]string) {
	var outTE *walk.TextEdit
	var mw *walk.MainWindow
	var windowIcon *walk.Icon
	counter := 0
	_, err := MainWindow{
		AssignTo: &mw,
		Title:    "抽♂词♂机",
		MinSize:  Size{1920, 1080},
		Layout:   VBox{},
		Children: []Widget{
			HSplitter{
				Children: []Widget{
					TextEdit{AssignTo: &outTE,
						ReadOnly: true,
						Font: Font{
							Family:    "Segoe UI",
							PointSize: 200,
							Bold:      true,
						}},
				},
			},
			PushButton{
				Text: "BOOM!",
				Font: Font{
					Family:    "Segoe UI",
					PointSize: 20,
					Bold:      true,
				},
				OnClicked: func() {
					outTE.SetText(getShuffleString(arr))
					ic, err := walk.NewIconFromImage(makeDigitImage(counter))
					if err != nil {
						return
					}
					counter++
					mw.SetIcon(ic)
					if windowIcon != nil {
						windowIcon.Dispose()
					}
					windowIcon = ic
				},
			},
		},
	}.Run()
	if err != nil {
		log.Panicln(err)
	}
}

//  A
// F B
//  G
// E C
//  D
var hexdigits = []int{0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71}

//0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B, 0x77, 0x1F, 0x4E, 0x3D, 0x4F, 0x47

type seg struct {
	sx, sy int
	dx, dy int
}

var segments = []seg{
	{0, 0, 1, 0},
	{1, 0, 0, 1},
	{1, 1, 0, 1},
	{0, 2, 1, 0},
	{0, 1, 0, 1},
	{0, 0, 0, 1},
	{0, 1, 1, 0},
}

func digit(im draw.Image, col color.Color, x, y, size, digit int) {
	n := hexdigits[digit]
	for _, s := range segments {
		if n&1 != 0 {
			xx, yy := x+s.sx*size, y+s.sy*size
			for i := 0; i <= size; i++ {
				im.Set(xx, yy, col)
				xx += s.dx
				yy += s.dy
			}
		}
		n >>= 1
	}
}

func makeDigitImage(n int) image.Image {
	im := image.NewRGBA(image.Rect(0, 0, 16, 16))
	for p := 11; p >= 0; p -= 5 {
		digit(im, color.Black, p, 5, 3, n%10)
		n /= 10
	}
	return im
}
